package ru.compscicenter.databases.zaikina.common;

import ru.compscicenter.databases.zaikina.common.commands.SysCommand;

import java.io.*;
import java.util.*;


public class Logger {
    private static final String NOT_PROCESSED_COMMANDS = "/NotProcessedCommands.log";
    private static final String PROCESSED_COMMANDS = "/ProcessedCommands.log";
    private final Integer nodeId;

    private ArrayList<SysCommand<?, ?>> notProcessedCommands;

    public Logger(Integer nodeId) {
        this.nodeId = nodeId;
    }

    public void addNotProcessedCommands(SysCommand<?, ?> command) {
        write(nodeId + NOT_PROCESSED_COMMANDS, command.toJSONString());
    }

    public void addProcessedCommands(SysCommand<?, ?> command) {
        write(nodeId + PROCESSED_COMMANDS, command.toJSONString());
    }

    public Collection<SysCommand<?, ?>> getNotProcessedCommands() {
        if (notProcessedCommands == null) {
            notProcessedCommands = read(nodeId + NOT_PROCESSED_COMMANDS);
            ArrayList<SysCommand<?, ?>> processedCommands = read(nodeId + PROCESSED_COMMANDS);
            notProcessedCommands.removeAll(processedCommands);
        }
        return notProcessedCommands;
    }

    public void normalize() {
        getNotProcessedCommands();
        LinkedList<String> strings = new LinkedList<String>();
        for (SysCommand command : notProcessedCommands) {
            strings.add(command.toJSONString());
        }
        write(nodeId + NOT_PROCESSED_COMMANDS, strings, false);
        write(nodeId + PROCESSED_COMMANDS, new LinkedList<String>(), false);
        notProcessedCommands = null;
    }

    private void write(String file, Collection<String> data, boolean append) {
        BufferedWriter writer;
        try {
            writer = new BufferedWriter(new FileWriter(file, append));
            for (String str : data) {
                writer.write(str + "\r\n");
            }
            writer.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void write(String file, String data) {
        Collection<String> collection = new LinkedList<String>();
        collection.add(data);
        write(file, collection, true);
    }

    private ArrayList<SysCommand<?, ?>> read(String file) {
        BufferedReader reader;
        try {
            reader = new BufferedReader(new FileReader(file));
        } catch (FileNotFoundException e) {
            return new ArrayList<SysCommand<?, ?>>();
        }

        ArrayList<SysCommand<?, ?>> data = new ArrayList<SysCommand<?, ?>>();
        try {
            while (reader.ready()) {
                data.add(SysCommand.parse(reader.readLine()));
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                reader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return data;
    }
}
